package com.ybear.ybcomponent.base.adapter

import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import java.util.Collections

/**
 * RecyclerView 拖拽帮助类
 */
open class DragRecyclerViewItemHelper : ItemTouchHelper.Callback() {

    interface IDragItemCallback {
        /**
         * 拖拽后更新数据源
         * @return 数据源列表，如果返回 null，则需要自行处理数据移动
         */
        fun onMoveData(fromPosition: Int, toPosition: Int): MutableList<*>?

        /**
         * 判断列表项是否可拖拽
         * @param position 列表项位置
         * @return true 可拖拽，false 不可拖拽
         */
        fun isItemDraggable(position: Int): Boolean

        /**
         * 判断从 fromPosition 移动到 toPosition 是否合法。
         * 此方法会检查 fromPosition 和 toPosition 之间的所有位置（不包括 fromPosition）是否都可拖动。
         * 如果遇到任何不可拖动的项，则返回 false，禁止移动。
         *
         * @param fromPosition 拖动前的列表项位置
         * @param toPosition 拖动后的列表项位置
         * @return true 移动合法，false 移动不合法
         */
        fun isMoveValid(fromPosition: Int, toPosition: Int): Boolean {
            if (fromPosition < toPosition) {
                // 向下拖动
                (fromPosition + 1..toPosition).forEach {
                    // 遍历 fromPosition 到 toPosition 之间的所有位置 (不包括 fromPosition)
                    // 如果遇到任何不可拖动的项，则禁止移动
                    if (!isItemDraggable(it)) return false
                }
            } else {
                // 向上拖动
                (toPosition until fromPosition).forEach {
                    // 遍历 toPosition 到 fromPosition 之间的所有位置 (不包括 fromPosition)
                    // 如果遇到任何不可拖动的项，则禁止移动
                    if (!isItemDraggable(it)) return false
                }
            }
            // 如果所有位置都可拖动，则允许移动
            return true
        }

        /**
         * 移动时的Item透明度
         * @return 透明度值 (0.0 - 1.0)
         */
        fun onMoveItemAlpha(): Float = 0.7F
    }

    private var recyclerView: RecyclerView? = null
    private var adapter: RecyclerView.Adapter<*>? = null // 修改 adapter 类型
    private var dragCallback: IDragItemCallback? = null

    fun init(recyclerView: RecyclerView) {
        this.recyclerView = recyclerView
        adapter = recyclerView.adapter
        dragCallback = adapter as? IDragItemCallback // 获取 IDragItemCallback 实例

        if (dragCallback == null) {
            throw NullPointerException("The adapter needs to implement the IDragItemCallback interface.")
        }
        ItemTouchHelper(this).attachToRecyclerView(recyclerView)
    }

    /**
     * 获取 RecyclerView 布局方向
     * @return RecyclerView.VERTICAL 或 RecyclerView.HORIZONTAL
     */
    private fun getOrientation(): Int {
        return when (val lm = recyclerView?.layoutManager) {
            is GridLayoutManager -> lm.orientation
            is LinearLayoutManager -> lm.orientation
            is StaggeredGridLayoutManager -> {
                // StaggeredGridLayoutManager 不直接提供 orientation 属性，
                // 需要根据 spanCount 和逆向布局来判断
                if (lm.spanCount == 1 && !lm.reverseLayout) {
                    RecyclerView.VERTICAL // 单列且非逆向布局，视为垂直
                } else {
                    RecyclerView.HORIZONTAL // 其他情况视为水平
                }
            }
            else -> RecyclerView.VERTICAL // 默认值
        }
    }

    override fun isLongPressDragEnabled(): Boolean = true // 开启长按拖拽

    override fun isItemViewSwipeEnabled(): Boolean = false // 关闭滑动删除

    override fun getMovementFlags(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder): Int {
        // 设置可拖动的方向
        val orientation = getOrientation()
        val dragFlags = when (orientation) {
            RecyclerView.VERTICAL -> ItemTouchHelper.START or ItemTouchHelper.END
            RecyclerView.HORIZONTAL -> ItemTouchHelper.UP or ItemTouchHelper.DOWN
            else -> 0
        }

        // 检查是否可拖拽
        val isDraggable = dragCallback?.isItemDraggable(viewHolder.bindingAdapterPosition) ?: false
        return makeMovementFlags(if (isDraggable) dragFlags else 0, 0)
    }

    override fun onMove(
        recyclerView: RecyclerView,
        viewHolder: RecyclerView.ViewHolder,
        target: RecyclerView.ViewHolder
    ): Boolean {
        // 当列表项被拖动时调用
        val fromPosition = viewHolder.bindingAdapterPosition
        val toPosition = target.bindingAdapterPosition

        // 判断移动是否合法
        if (dragCallback?.isMoveValid(fromPosition, toPosition) == false) return false

        // 更新数据源
        dragCallback?.onMoveData(fromPosition, toPosition)?.let { dataList ->
            Collections.swap(dataList, fromPosition, toPosition)
            adapter?.notifyItemMoved(fromPosition, toPosition) // 安全调用 notifyItemMoved()
        }
        return true
    }

    override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
        // 不处理滑动删除
    }

    override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {
        super.onSelectedChanged(viewHolder, actionState)
        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
            viewHolder?.itemView?.alpha = dragCallback?.onMoveItemAlpha() ?: 1.0F
        }
    }

    override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {
        super.clearView(recyclerView, viewHolder)
        viewHolder.itemView.alpha = 1.0F
    }
}